home *** CD-ROM | disk | FTP | other *** search
/ Freelog 115 / FreelogNo115-MaiJuin2013.iso / Internet / Filezilla Server / FileZilla_Server-0_9_41.exe / source / AsyncSocketEx.cpp < prev    next >
C/C++ Source or Header  |  2011-11-06  |  53KB  |  1,913 lines

  1. /*CAsyncSocketEx by Tim Kosse (Tim.Kosse@gmx.de)
  2.             Version 1.3 (2003-04-26)
  3. --------------------------------------------------------
  4.  
  5. Introduction:
  6. -------------
  7.  
  8. CAsyncSocketEx is a replacement for the MFC class CAsyncSocket.
  9. This class was written because CAsyncSocket is not the fastest WinSock
  10. wrapper and it's very hard to add new functionality to CAsyncSocket
  11. derived classes. This class offers the same functionality as CAsyncSocket.
  12. Also, CAsyncSocketEx offers some enhancements which were not possible with
  13. CAsyncSocket without some tricks.
  14.  
  15. How do I use it?
  16. ----------------
  17. Basically exactly like CAsyncSocket.
  18. To use CAsyncSocketEx, just replace all occurrences of CAsyncSocket in your
  19. code with CAsyncSocketEx, if you did not enhance CAsyncSocket yourself in
  20. any way, you won't have to change anything else in your code.
  21.  
  22. Why is CAsyncSocketEx faster?
  23. -----------------------------
  24.  
  25. CAsyncSocketEx is slightly faster when dispatching notification event messages.
  26. First have a look at the way CAsyncSocket works. For each thread that uses
  27. CAsyncSocket, a window is created. CAsyncSocket calls WSAAsyncSelect with
  28. the handle of that window. Until here, CAsyncSocketEx works the same way.
  29. But CAsyncSocket uses only one window message (WM_SOCKET_NOTIFY) for all
  30. sockets within one thread. When the window recieve WM_SOCKET_NOTIFY, wParam
  31. contains the socket handle and the window looks up an CAsyncSocket instance
  32. using a map. CAsyncSocketEx works differently. It's helper window uses a
  33. wide range of different window messages (WM_USER through 0xBFFF) and passes
  34. a different message to WSAAsyncSelect for each socket. When a message in
  35. the specified range is received, CAsyncSocketEx looks up the pointer to a
  36. CAsyncSocketEx instance in an Array using the index of message - WM_USER.
  37. As you can see, CAsyncSocketEx uses the helper window in a more efficient
  38. way, as it don't have to use the slow maps to lookup it's own instance.
  39. Still, speed increase is not very much, but it may be noticeable when using
  40. a lot of sockets at the same time.
  41. Please note that the changes do not affect the raw data throughput rate,
  42. CAsyncSocketEx only dispatches the notification messages faster.
  43.  
  44. What else does CAsyncSocketEx offer?
  45. ------------------------------------
  46.  
  47. CAsyncSocketEx offers a flexible layer system. One example is the proxy layer.
  48. Just create an instance of the proxy layer, configure it and add it to the layer
  49. chain of your CAsyncSocketEx instance. After that, you can connect through
  50. proxies.
  51. Benefit: You don't have to change much to use the layer system.
  52. Another layer that is currently in development is the SSL layer to establish
  53. SSL encrypted connections.
  54.  
  55. License
  56. -------
  57.  
  58. Feel free to use this class, as long as you don't claim that you wrote it
  59. and this copyright notice stays intact in the source files.
  60. If you use this class in commercial applications, please send a short message
  61. to tim.kosse@gmx.de
  62. */
  63.  
  64. #include "stdafx.h"
  65. #include "AsyncSocketEx.h"
  66. #include "wtypes.h"
  67. #include "oleauto.h"
  68. #include "atlconv.h"
  69.  
  70. #ifndef NOLAYERS
  71. #include "AsyncSocketExLayer.h"
  72. #endif //NOLAYERS
  73.  
  74. #ifdef _DEBUG
  75. #undef THIS_FILE
  76. static char THIS_FILE[]=__FILE__;
  77. #endif
  78.  
  79. #ifndef CCRITICALSECTIONWRAPPERINCLUDED
  80. class CCriticalSectionWrapper
  81. {
  82. public:
  83.     CCriticalSectionWrapper()
  84.     {
  85.         m_bInitialized = TRUE;
  86.         InitializeCriticalSection(&m_criticalSection);
  87.     }
  88.  
  89.     ~CCriticalSectionWrapper()
  90.     {
  91.         if (m_bInitialized)
  92.             DeleteCriticalSection(&m_criticalSection);
  93.         m_bInitialized = FALSE;
  94.     }
  95.  
  96.     void Lock()
  97.     {
  98.         if (m_bInitialized)
  99.             EnterCriticalSection(&m_criticalSection);
  100.     }
  101.     void Unlock()
  102.     {
  103.         if (m_bInitialized)
  104.             LeaveCriticalSection(&m_criticalSection);
  105.     }
  106. protected:
  107.     CRITICAL_SECTION m_criticalSection;
  108.     BOOL m_bInitialized;
  109. };
  110. #define CCRITICALSECTIONWRAPPERINCLUDED
  111. #endif
  112.  
  113. CCriticalSectionWrapper CAsyncSocketEx::m_sGlobalCriticalSection;
  114. CAsyncSocketEx::t_AsyncSocketExThreadDataList *CAsyncSocketEx::m_spAsyncSocketExThreadDataList = 0;
  115. HMODULE CAsyncSocketEx::m_hDll = 0;
  116. t_getaddrinfo CAsyncSocketEx::p_getaddrinfo = 0;
  117. t_freeaddrinfo CAsyncSocketEx::p_freeaddrinfo = 0;
  118.  
  119.  
  120. #ifndef _AFX
  121. #ifndef VERIFY
  122. #define VERIFY(x) (void(x))
  123. #endif //VERIFY
  124. #ifndef ASSERT
  125. #define ASSERT(x)
  126. #endif //ASSERT
  127. #endif //_AFX
  128.  
  129. /////////////////////////////
  130. //Helper Window class
  131. #define WM_SOCKETEX_NOTIFY (WM_USER+3)
  132. #define MAX_SOCKETS (0xBFFF-WM_SOCKETEX_NOTIFY+1)
  133.  
  134. class CAsyncSocketExHelperWindow
  135. {
  136. public:
  137.     CAsyncSocketExHelperWindow(CAsyncSocketEx::t_AsyncSocketExThreadData* pThreadData)
  138.     {
  139.         //Initialize data
  140.         m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[512]; //Reserve space for 512 active sockets
  141.         memset(m_pAsyncSocketExWindowData, 0, 512*sizeof(t_AsyncSocketExWindowData));
  142.         m_nWindowDataSize=512;
  143.         m_nSocketCount=0;
  144.         m_nWindowDataPos=0;
  145.         m_pThreadData = pThreadData;
  146.  
  147.         //Create window
  148.         WNDCLASSEX wndclass;
  149.         wndclass.cbSize=sizeof wndclass;
  150.         wndclass.style=0;
  151.         wndclass.lpfnWndProc=WindowProc;
  152.         wndclass.cbClsExtra=0;
  153.         wndclass.cbWndExtra=0;
  154.         wndclass.hInstance=GetModuleHandle(0);
  155.         wndclass.hIcon=0;
  156.         wndclass.hCursor=0;
  157.         wndclass.hbrBackground=0;
  158.         wndclass.lpszMenuName=0;
  159.         wndclass.lpszClassName=_T("CAsyncSocketEx Helper Window");
  160.         wndclass.hIconSm=0;
  161.  
  162.         RegisterClassEx(&wndclass);
  163.  
  164.         m_hWnd=CreateWindow(_T("CAsyncSocketEx Helper Window"), _T("CAsyncSocketEx Helper Window"), 0, 0, 0, 0, 0, 0, 0, 0, GetModuleHandle(0));
  165.         ASSERT(m_hWnd);
  166.         SetWindowLongPtr(m_hWnd, GWLP_USERDATA, (LONG_PTR)this);
  167.     };
  168.  
  169.     virtual ~CAsyncSocketExHelperWindow()
  170.     {
  171.         //Clean up socket storage
  172.         delete [] m_pAsyncSocketExWindowData;
  173.         m_pAsyncSocketExWindowData=0;
  174.         m_nWindowDataSize=0;
  175.         m_nSocketCount=0;
  176.  
  177.         //Destroy window
  178.         if (m_hWnd)
  179.         {
  180.             DestroyWindow(m_hWnd);
  181.             m_hWnd=0;
  182.         }
  183.     }
  184.  
  185.     //Adds a socket to the list of attached sockets
  186.     BOOL AddSocket(CAsyncSocketEx *pSocket, int &nSocketIndex)
  187.     {
  188.         ASSERT(pSocket);
  189.         if (!m_nWindowDataSize)
  190.         {
  191.             ASSERT(!m_nSocketCount);
  192.             m_nWindowDataSize=512;
  193.             m_pAsyncSocketExWindowData=new t_AsyncSocketExWindowData[512]; //Reserve space for 512 active sockets
  194.             memset(m_pAsyncSocketExWindowData, 0, 512*sizeof(t_AsyncSocketExWindowData));
  195.         }
  196.  
  197.         if (nSocketIndex!=-1)
  198.         {
  199.             ASSERT(m_pAsyncSocketExWindowData);
  200.             ASSERT(m_nWindowDataSize>nSocketIndex);
  201.             ASSERT(m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket==pSocket);
  202.             ASSERT(m_nSocketCount);
  203.             return TRUE;
  204.         }
  205.  
  206.         //Increase socket storage if too small
  207.         if (m_nSocketCount>=(m_nWindowDataSize-10))
  208.         {
  209.             int nOldWindowDataSize=m_nWindowDataSize;
  210.             ASSERT(m_nWindowDataSize<MAX_SOCKETS);
  211.             m_nWindowDataSize+=512;
  212.             if (m_nWindowDataSize>MAX_SOCKETS)
  213.                 m_nWindowDataSize=MAX_SOCKETS;
  214.             t_AsyncSocketExWindowData *tmp=m_pAsyncSocketExWindowData;
  215.             m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[m_nWindowDataSize];
  216.             memcpy(m_pAsyncSocketExWindowData, tmp, nOldWindowDataSize * sizeof(t_AsyncSocketExWindowData));
  217.             memset(m_pAsyncSocketExWindowData+nOldWindowDataSize, 0, (m_nWindowDataSize-nOldWindowDataSize)*sizeof(t_AsyncSocketExWindowData));
  218.             delete [] tmp;
  219.         }
  220.  
  221.         //Search for free slot
  222.         for (int i=m_nWindowDataPos;i<(m_nWindowDataSize+m_nWindowDataPos);i++)
  223.         {
  224.             if (!m_pAsyncSocketExWindowData[i%m_nWindowDataSize].m_pSocket)
  225.             {
  226.                 m_pAsyncSocketExWindowData[i%m_nWindowDataSize].m_pSocket=pSocket;
  227.                 nSocketIndex=i%m_nWindowDataSize;
  228.                 m_nWindowDataPos=(i+1)%m_nWindowDataSize;
  229.                 m_nSocketCount++;
  230.                 return TRUE;
  231.             }
  232.         }
  233.  
  234.         //No slot found, maybe there are too much sockets!
  235.         return FALSE;
  236.     }
  237.  
  238.     //Removes a socket from the socket storage
  239.     BOOL RemoveSocket(CAsyncSocketEx *pSocket, int &nSocketIndex)
  240.     {
  241.         ASSERT(pSocket);
  242.         if (nSocketIndex==-1)
  243.             return TRUE;
  244.  
  245.         // Remove additional messages from queue
  246.         MSG msg;
  247.         while (PeekMessage(&msg, m_hWnd, WM_SOCKETEX_NOTIFY + nSocketIndex, WM_SOCKETEX_NOTIFY + nSocketIndex, PM_REMOVE));
  248.  
  249.         ASSERT(m_pAsyncSocketExWindowData);
  250.         ASSERT(m_nWindowDataSize>0);
  251.         ASSERT(m_nSocketCount>0);
  252.         ASSERT(m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket==pSocket);
  253.         m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket=0;
  254.         nSocketIndex=-1;
  255.         m_nSocketCount--;
  256.  
  257.         return TRUE;
  258.     }
  259.  
  260.     void RemoveLayers(CAsyncSocketEx *pOrigSocket)
  261.     {
  262.         // Remove all layer messages from old socket
  263.         std::list<MSG> msgList;
  264.         MSG msg;
  265.         while (PeekMessage(&msg, m_hWnd, WM_USER, WM_USER, PM_REMOVE))
  266.         {
  267.             //Verify parameters, lookup socket and notification message
  268.             //Verify parameters
  269.             if (msg.wParam >= static_cast<UINT>(m_nWindowDataSize)) //Index is within socket storage
  270.                 continue;
  271.  
  272.             CAsyncSocketEx *pSocket = m_pAsyncSocketExWindowData[msg.wParam].m_pSocket;
  273.             CAsyncSocketExLayer::t_LayerNotifyMsg *pMsg=(CAsyncSocketExLayer::t_LayerNotifyMsg *)msg.lParam;
  274.             if (!pMsg || !pSocket || pSocket == pOrigSocket || pSocket->m_SocketData.hSocket != pMsg->hSocket)
  275.             {
  276.                 delete pMsg;
  277.                 continue;
  278.             }
  279.  
  280.             msgList.push_back(msg);
  281.         }
  282.  
  283.         for (std::list<MSG>::iterator iter = msgList.begin(); iter != msgList.end(); iter++)
  284.             PostMessage(m_hWnd, iter->message, iter->wParam, iter->lParam);
  285.     }
  286.  
  287.     //Processes event notifications sent by the sockets or the layers
  288.     static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  289.     {
  290.         if (message>=WM_SOCKETEX_NOTIFY)
  291.         {
  292.             //Verify parameters
  293.             ASSERT(hWnd);
  294.             CAsyncSocketExHelperWindow *pWnd=(CAsyncSocketExHelperWindow *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
  295.             ASSERT(pWnd);
  296.             
  297.             if (message<static_cast<UINT>(WM_SOCKETEX_NOTIFY+pWnd->m_nWindowDataSize)) //Index is within socket storage
  298.             {
  299.                 //Lookup socket and verify if it's valid
  300.                 CAsyncSocketEx *pSocket=pWnd->m_pAsyncSocketExWindowData[message-WM_SOCKETEX_NOTIFY].m_pSocket;
  301.                 SOCKET hSocket=wParam;
  302.                 if (!pSocket)
  303.                     return 0;
  304.                 if (hSocket==INVALID_SOCKET)
  305.                     return 0;
  306.                 if (pSocket->m_SocketData.hSocket != hSocket)
  307.                     return 0;
  308.                 
  309.                 int nEvent=lParam&0xFFFF;
  310.                 int nErrorCode=lParam>>16;
  311.  
  312.                 //Dispatch notification
  313. #ifndef NOLAYERS
  314.                 if (!pSocket->m_pFirstLayer)
  315.                 {
  316. #endif //NOLAYERS
  317.                     //Dispatch to CAsyncSocketEx instance
  318.                     switch (nEvent)
  319.                     {
  320.                     case FD_READ:
  321. #ifndef NOSOCKETSTATES
  322.                         if (pSocket->GetState() == connecting && !nErrorCode)
  323.                         {
  324.                             pSocket->m_nPendingEvents |= FD_READ;
  325.                             break;
  326.                         }
  327.                         else if (pSocket->GetState() == attached)
  328.                             pSocket->SetState(connected);
  329.                         if (pSocket->GetState() != connected)
  330.                             break;
  331.  
  332.                         // Ignore further FD_READ events after FD_CLOSE has been received
  333.                         if (pSocket->m_SocketData.onCloseCalled)
  334.                             break;
  335. #endif //NOSOCKETSTATES
  336.                         
  337.                         if (pSocket->m_lEvent & FD_READ)
  338.                         {
  339.                             DWORD nBytes = 0;
  340.                             if (!nErrorCode)
  341.                                 if (!pSocket->IOCtl(FIONREAD, &nBytes))
  342.                                     nErrorCode = WSAGetLastError();
  343. #ifndef NOSOCKETSTATES
  344.                             if (nErrorCode)
  345.                                 pSocket->SetState(aborted);
  346. #endif //NOSOCKETSTATES
  347.                             if (nBytes != 0 || nErrorCode != 0)
  348.                                 pSocket->OnReceive(nErrorCode);
  349.                         }
  350.                         break;
  351.                     case FD_FORCEREAD: //Forceread does not check if there's data waiting
  352. #ifndef NOSOCKETSTATES
  353.                         if (pSocket->GetState() == connecting && !nErrorCode)
  354.                         {
  355.                             pSocket->m_nPendingEvents |= FD_FORCEREAD;
  356.                             break;
  357.                         }
  358.                         else if (pSocket->GetState() == attached)
  359.                             pSocket->SetState(connected);
  360.                         if (pSocket->GetState() != connected)
  361.                             break;
  362. #endif //NOSOCKETSTATES
  363.                         if (pSocket->m_lEvent & FD_READ)
  364.                         {
  365. #ifndef NOSOCKETSTATES
  366.                             if (nErrorCode)
  367.                                 pSocket->SetState(aborted);
  368. #endif //NOSOCKETSTATES
  369.                             pSocket->OnReceive(nErrorCode);
  370.                         }
  371.                         break;
  372.                     case FD_WRITE:
  373. #ifndef NOSOCKETSTATES
  374.                         if (pSocket->GetState() == connecting && !nErrorCode)
  375.                         {
  376.                             pSocket->m_nPendingEvents |= FD_WRITE;
  377.                             break;
  378.                         }
  379.                         else if (pSocket->GetState() == attached && !nErrorCode)
  380.                             pSocket->SetState(connected);
  381.                         if (pSocket->GetState() != connected)
  382.                             break;
  383. #endif //NOSOCKETSTATES
  384.                         if (pSocket->m_lEvent & FD_WRITE)
  385.                         {
  386. #ifndef NOSOCKETSTATES
  387.                             if (nErrorCode)
  388.                                 pSocket->SetState(aborted);
  389. #endif //NOSOCKETSTATES
  390.                             pSocket->OnSend(nErrorCode);
  391.                         }
  392.                         break;
  393.                     case FD_CONNECT:
  394. #ifndef NOSOCKETSTATES
  395.                         if (pSocket->GetState() == connecting)
  396.                         {
  397.                             if (nErrorCode && pSocket->m_SocketData.nextAddr)
  398.                             {
  399.                                 if (pSocket->TryNextProtocol())
  400.                                     break;
  401.                             }
  402.                             pSocket->SetState(connected);
  403.                         }
  404.                         else if (pSocket->GetState() == attached && !nErrorCode)
  405.                             pSocket->SetState(connected);
  406. #endif //NOSOCKETSTATES
  407.                         if (pSocket->m_lEvent & FD_CONNECT)
  408.                             pSocket->OnConnect(nErrorCode);
  409. #ifndef NOSOCKETSTATES
  410.                         if (!nErrorCode)
  411.                         {
  412.                             if ((pSocket->m_nPendingEvents&FD_READ) && pSocket->GetState() == connected)
  413.                                 pSocket->OnReceive(0);
  414.                             if ((pSocket->m_nPendingEvents&FD_FORCEREAD) && pSocket->GetState() == connected)
  415.                                 pSocket->OnReceive(0);
  416.                             if ((pSocket->m_nPendingEvents&FD_WRITE) && pSocket->GetState() == connected)
  417.                                 pSocket->OnSend(0);
  418.                         }
  419.                         pSocket->m_nPendingEvents = 0;
  420. #endif
  421.                         break;
  422.                     case FD_ACCEPT:
  423. #ifndef NOSOCKETSTATES
  424.                         if (pSocket->GetState() != listening && pSocket->GetState() != attached)
  425.                             break;
  426. #endif //NOSOCKETSTATES
  427.                         if (pSocket->m_lEvent & FD_ACCEPT)
  428.                             pSocket->OnAccept(nErrorCode);
  429.                         break;
  430.                     case FD_CLOSE:
  431. #ifndef NOSOCKETSTATES
  432.                         if (pSocket->GetState() != connected && pSocket->GetState() != attached)
  433.                             break;
  434.  
  435.                         // If there are still bytes left to read, call OnReceive instead of 
  436.                         // OnClose and trigger a new OnClose
  437.                         DWORD nBytes = 0;
  438.                         if (!nErrorCode && pSocket->IOCtl(FIONREAD, &nBytes))
  439.                         {
  440.                             if (nBytes > 0)
  441.                             {
  442.                                 // Just repeat message.
  443.                                 PostMessage(hWnd, message, wParam, lParam);
  444.                                 pSocket->m_SocketData.onCloseCalled = true;                                
  445.                                 pSocket->OnReceive(WSAESHUTDOWN);
  446.                                 break;
  447.                             }
  448.                         }
  449.  
  450.                         pSocket->SetState(nErrorCode?aborted:closed);
  451. #endif //NOSOCKETSTATES
  452.                         pSocket->OnClose(nErrorCode);
  453.                         break;
  454.                     }
  455.                 }
  456. #ifndef NOLAYERS
  457.                 else //Dispatch notification to the lowest layer
  458.                 {
  459.                     if (nEvent == FD_READ)
  460.                     {
  461.                         // Ignore further FD_READ events after FD_CLOSE has been received
  462.                         if (pSocket->m_SocketData.onCloseCalled)
  463.                             return 0;
  464.  
  465.                         DWORD nBytes;
  466.                         if (!pSocket->IOCtl(FIONREAD, &nBytes))
  467.                             nErrorCode = WSAGetLastError();
  468.                         if (nBytes != 0 || nErrorCode != 0)
  469.                             pSocket->m_pLastLayer->CallEvent(nEvent, nErrorCode);
  470.                     }
  471.                     else if (nEvent == FD_CLOSE)
  472.                     {
  473.                         // If there are still bytes left to read, call OnReceive instead of 
  474.                         // OnClose and trigger a new OnClose
  475.                         DWORD nBytes = 0;
  476.                         if (!nErrorCode && pSocket->IOCtl(FIONREAD, &nBytes))
  477.                         {
  478.                             if (nBytes > 0)
  479.                             {
  480.                                 // Just repeat message.
  481.                                 pSocket->ResendCloseNotify();
  482.                                 pSocket->m_pLastLayer->CallEvent(FD_READ, 0);
  483.                                 return 0;
  484.                             }
  485.                         }
  486.                         pSocket->m_SocketData.onCloseCalled = true;
  487.                         pSocket->m_pLastLayer->CallEvent(nEvent, nErrorCode);
  488.                     }
  489.                     else
  490.                         pSocket->m_pLastLayer->CallEvent(nEvent, nErrorCode);
  491.                 }
  492.             }
  493. #endif //NOLAYERS
  494.             return 0;
  495.         }
  496. #ifndef NOLAYERS
  497.         else if (message == WM_USER) //Notification event sent by a layer
  498.         {
  499.             //Verify parameters, lookup socket and notification message
  500.             //Verify parameters
  501.             ASSERT(hWnd);
  502.             CAsyncSocketExHelperWindow *pWnd=(CAsyncSocketExHelperWindow *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
  503.             ASSERT(pWnd);
  504.             
  505.             if (wParam >= static_cast<UINT>(pWnd->m_nWindowDataSize)) //Index is within socket storage
  506.             {
  507.                 return 0;
  508.             }
  509.             
  510.             CAsyncSocketEx *pSocket=pWnd->m_pAsyncSocketExWindowData[wParam].m_pSocket;
  511.             CAsyncSocketExLayer::t_LayerNotifyMsg *pMsg=(CAsyncSocketExLayer::t_LayerNotifyMsg *)lParam;
  512.             if (!pMsg || !pSocket || pSocket->m_SocketData.hSocket != pMsg->hSocket)
  513.             {
  514.                 delete pMsg;
  515.                 return 0;
  516.             }
  517.             int nEvent=pMsg->lEvent&0xFFFF;
  518.             int nErrorCode=pMsg->lEvent>>16;
  519.             
  520.             //Dispatch to layer
  521.             if (pMsg->pLayer)
  522.                 pMsg->pLayer->CallEvent(nEvent, nErrorCode);
  523.             else
  524.             {
  525.                 //Dispatch to CAsyncSocketEx instance
  526.                 switch (nEvent)
  527.                 {
  528.                 case FD_READ:
  529. #ifndef NOSOCKETSTATES
  530.                     if (pSocket->GetState() == connecting && !nErrorCode)
  531.                     {
  532.                         pSocket->m_nPendingEvents |= FD_READ;
  533.                         break;
  534.                     }
  535.                     else if (pSocket->GetState() == attached && !nErrorCode)
  536.                         pSocket->SetState(connected);
  537.                     if (pSocket->GetState() != connected)
  538.                         break;
  539. #endif //NOSOCKETSTATES
  540.                     if (pSocket->m_lEvent & FD_READ)
  541.                     {
  542. #ifndef NOSOCKETSTATES
  543.                         if (nErrorCode)
  544.                             pSocket->SetState(aborted);
  545. #endif //NOSOCKETSTATES
  546.                         pSocket->OnReceive(nErrorCode);
  547.                     }
  548.                     break;
  549.                 case FD_FORCEREAD: //Forceread does not check if there's data waiting
  550. #ifndef NOSOCKETSTATES
  551.                     if (pSocket->GetState() == connecting && !nErrorCode)
  552.                     {
  553.                         pSocket->m_nPendingEvents |= FD_FORCEREAD;
  554.                         break;
  555.                     }
  556.                     else if (pSocket->GetState() == attached && !nErrorCode)
  557.                         pSocket->SetState(connected);
  558.                     if (pSocket->GetState() != connected)
  559.                         break;
  560. #endif //NOSOCKETSTATES
  561.                     if (pSocket->m_lEvent & FD_READ)
  562.                     {
  563. #ifndef NOSOCKETSTATES
  564.                         if (nErrorCode)
  565.                             pSocket->SetState(aborted);
  566. #endif //NOSOCKETSTATES
  567.                         pSocket->OnReceive(nErrorCode);
  568.                     }
  569.                     break;
  570.                 case FD_WRITE:
  571. #ifndef NOSOCKETSTATES
  572.                     if (pSocket->GetState() == connecting && !nErrorCode)
  573.                     {
  574.                         pSocket->m_nPendingEvents |= FD_WRITE;
  575.                         break;
  576.                     }
  577.                     else if (pSocket->GetState() == attached && !nErrorCode)
  578.                         pSocket->SetState(connected);
  579.                     if (pSocket->GetState() != connected)
  580.                         break;
  581. #endif //NOSOCKETSTATES
  582.                     if (pSocket->m_lEvent & FD_WRITE)
  583.                     {
  584. #ifndef NOSOCKETSTATES
  585.                         if (nErrorCode)
  586.                             pSocket->SetState(aborted);
  587. #endif //NOSOCKETSTATES
  588.                         pSocket->OnSend(nErrorCode);
  589.                     }
  590.                     break;
  591.                 case FD_CONNECT:
  592. #ifndef NOSOCKETSTATES
  593.                     if (pSocket->GetState() == connecting)
  594.                         pSocket->SetState(connected);
  595.                     else if (pSocket->GetState() == attached && !nErrorCode)
  596.                         pSocket->SetState(connected);
  597. #endif //NOSOCKETSTATES
  598.                     if (pSocket->m_lEvent & FD_CONNECT)
  599.                         pSocket->OnConnect(nErrorCode);
  600. #ifndef NOSOCKETSTATES
  601.                     if (!nErrorCode)
  602.                     {
  603.                         if (((pSocket->m_nPendingEvents&FD_READ) && pSocket->GetState() == connected) && (pSocket->m_lEvent & FD_READ))
  604.                             pSocket->OnReceive(0);
  605.                         if (((pSocket->m_nPendingEvents&FD_FORCEREAD) && pSocket->GetState() == connected) && (pSocket->m_lEvent & FD_READ))
  606.                             pSocket->OnReceive(0);
  607.                         if (((pSocket->m_nPendingEvents&FD_WRITE) && pSocket->GetState() == connected) && (pSocket->m_lEvent & FD_WRITE))
  608.                             pSocket->OnSend(0);
  609.                     }
  610.                     pSocket->m_nPendingEvents = 0;
  611. #endif //NOSOCKETSTATES
  612.                     break;
  613.                 case FD_ACCEPT:
  614. #ifndef NOSOCKETSTATES
  615.                     if ((pSocket->GetState() == listening || pSocket->GetState() == attached) && (pSocket->m_lEvent & FD_ACCEPT))
  616. #endif //NOSOCKETSTATES
  617.                     {
  618.                         pSocket->OnAccept(nErrorCode);
  619.                     }
  620.                     break;
  621.                 case FD_CLOSE:
  622. #ifndef NOSOCKETSTATES
  623.                     if ((pSocket->GetState() == connected || pSocket->GetState() == attached) && (pSocket->m_lEvent & FD_CLOSE))
  624.                     {
  625.                         pSocket->SetState(nErrorCode?aborted:closed);
  626. #else
  627.                     {
  628. #endif //NOSOCKETSTATES
  629.                         pSocket->OnClose(nErrorCode);
  630.                     }
  631.                     break;
  632.                 }
  633.             }
  634.             delete pMsg;
  635.             return 0;
  636.         }
  637. #endif //NOLAYERS
  638.         else if (message == WM_USER+1)
  639.         {
  640.             // WSAAsyncGetHostByName reply
  641.  
  642.             // Verify parameters
  643.             ASSERT(hWnd);
  644.             CAsyncSocketExHelperWindow *pWnd = (CAsyncSocketExHelperWindow *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
  645.             ASSERT(pWnd);
  646.  
  647.             CAsyncSocketEx *pSocket = NULL;
  648.             for (int i = 0; i < pWnd->m_nWindowDataSize; i++)
  649.             {
  650.                 pSocket = pWnd->m_pAsyncSocketExWindowData[i].m_pSocket;
  651.                 if (pSocket && pSocket->m_hAsyncGetHostByNameHandle &&
  652.                     pSocket->m_hAsyncGetHostByNameHandle == (HANDLE)wParam)
  653.                     break;
  654.             }
  655.             if (!pSocket)
  656.                 return 0;
  657.  
  658.             int nErrorCode = lParam >> 16;
  659.             if (nErrorCode)
  660.             {
  661.                 pSocket->OnConnect(nErrorCode);
  662.                 return 0;
  663.             }
  664.  
  665.             SOCKADDR_IN sockAddr;
  666.             memset(&sockAddr,0,sizeof(sockAddr));
  667.             sockAddr.sin_family=AF_INET;
  668.             sockAddr.sin_addr.s_addr = ((LPIN_ADDR)((LPHOSTENT)pSocket->m_pAsyncGetHostByNameBuffer)->h_addr)->s_addr;
  669.  
  670.             sockAddr.sin_port = htons(pSocket->m_nAsyncGetHostByNamePort);
  671.  
  672.             BOOL res = pSocket->Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  673.             delete [] pSocket->m_pAsyncGetHostByNameBuffer;
  674.             pSocket->m_pAsyncGetHostByNameBuffer=0;
  675.             pSocket->m_hAsyncGetHostByNameHandle=0;
  676.  
  677.             if (!res)
  678.                 if (GetLastError()!=WSAEWOULDBLOCK)
  679.                     pSocket->OnConnect(GetLastError());
  680.             return 0;
  681.         }
  682.         else if (message == WM_USER + 2)
  683.         {
  684.             //Verify parameters, lookup socket and notification message
  685.             //Verify parameters
  686.             if (!hWnd)
  687.                 return 0;
  688.  
  689.             CAsyncSocketExHelperWindow *pWnd=(CAsyncSocketExHelperWindow *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
  690.             if (!pWnd)
  691.                 return 0;
  692.  
  693.             if (wParam >= static_cast<UINT>(pWnd->m_nWindowDataSize)) //Index is within socket storage
  694.                 return 0;
  695.             
  696.             CAsyncSocketEx *pSocket = pWnd->m_pAsyncSocketExWindowData[wParam].m_pSocket;
  697.             if (!pSocket)
  698.                 return 0;
  699.             
  700.             // Process pending callbacks
  701.             std::list<t_callbackMsg> tmp;
  702.             tmp.swap(pSocket->m_pendingCallbacks);
  703.             pSocket->OnLayerCallback(tmp);
  704.         }
  705.         else if (message == WM_TIMER)
  706.         {
  707.             if (wParam != 1)
  708.                 return 0;
  709.             
  710.             ASSERT(hWnd);
  711.             CAsyncSocketExHelperWindow *pWnd=(CAsyncSocketExHelperWindow *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
  712.             ASSERT(pWnd);
  713.  
  714.             if (pWnd->m_pThreadData->layerCloseNotify.empty())
  715.             {
  716.                 KillTimer(hWnd, 1);
  717.                 return 0;
  718.             }
  719.             CAsyncSocketEx* socket = pWnd->m_pThreadData->layerCloseNotify.front();
  720.             pWnd->m_pThreadData->layerCloseNotify.pop_front();
  721.             if (pWnd->m_pThreadData->layerCloseNotify.empty())
  722.                 KillTimer(hWnd, 1);
  723.  
  724.             PostMessage(hWnd, socket->m_SocketData.nSocketIndex + WM_SOCKETEX_NOTIFY, socket->m_SocketData.hSocket, FD_CLOSE);
  725.             return 0;
  726.         }
  727.         return DefWindowProc(hWnd, message, wParam, lParam);
  728.     }
  729.  
  730.     HWND CAsyncSocketExHelperWindow::GetHwnd()
  731.     {
  732.         return m_hWnd;
  733.     }
  734.  
  735. private:
  736.     HWND m_hWnd;
  737.     struct t_AsyncSocketExWindowData
  738.     {
  739.         CAsyncSocketEx *m_pSocket;
  740.     } *m_pAsyncSocketExWindowData;
  741.     int m_nWindowDataSize;
  742.     int m_nWindowDataPos;
  743.     int m_nSocketCount;
  744.     CAsyncSocketEx::t_AsyncSocketExThreadData* m_pThreadData;
  745. };
  746.  
  747. //////////////////////////////////////////////////////////////////////
  748. // Konstruktion/Destruktion
  749. //////////////////////////////////////////////////////////////////////
  750.  
  751. CAsyncSocketEx::CAsyncSocketEx()
  752. {
  753.     m_SocketData.hSocket = INVALID_SOCKET;
  754.     m_SocketData.nSocketIndex = -1;
  755.     m_SocketData.nFamily = AF_UNSPEC;
  756.     m_SocketData.onCloseCalled = false;
  757.     m_pLocalAsyncSocketExThreadData = 0;
  758.  
  759. #ifndef NOSOCKETSTATES
  760.     m_nPendingEvents = 0;
  761.     m_nState = notsock;
  762. #endif //NOSOCKETSTATES
  763.  
  764. #ifndef NOLAYERS
  765.     m_pFirstLayer = 0;
  766.     m_pLastLayer = 0;
  767. #endif //NOLAYERS
  768.     m_pAsyncGetHostByNameBuffer = NULL;
  769.     m_hAsyncGetHostByNameHandle = NULL;
  770.  
  771.     m_nSocketPort = 0;
  772.     m_lpszSocketAddress = 0;
  773.  
  774.     m_SocketData.addrInfo = 0;
  775.     m_SocketData.nextAddr = 0;
  776. }
  777.  
  778. CAsyncSocketEx::~CAsyncSocketEx()
  779. {
  780.     Close();
  781.     FreeAsyncSocketExInstance();
  782. }
  783.  
  784. BOOL CAsyncSocketEx::Create(UINT nSocketPort /*=0*/, int nSocketType /*=SOCK_STREAM*/, long lEvent /*=FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE*/, LPCTSTR lpszSocketAddress /*=NULL*/, int nFamily /*=AF_INET*/, bool reusable /*=false*/)
  785. {
  786.     ASSERT(GetSocketHandle() == INVALID_SOCKET);
  787.  
  788.     //Close the socket, although this should not happen
  789.     if (GetSocketHandle() != INVALID_SOCKET)
  790.     {
  791.         WSASetLastError(WSAEALREADY);
  792.         return FALSE;
  793.     }
  794.  
  795.     BOOL res = InitAsyncSocketExInstance();
  796.     ASSERT(res);
  797.     if (!res)
  798.     {
  799.         WSASetLastError(WSANOTINITIALISED);
  800.         return FALSE;
  801.     }
  802.  
  803.     m_SocketData.nFamily = nFamily;
  804.  
  805. #ifndef NOLAYERS
  806.     if (m_pFirstLayer)
  807.     {
  808.         res = m_pFirstLayer->Create(nSocketPort, nSocketType, lEvent, lpszSocketAddress, nFamily, reusable);
  809. #ifndef NOSOCKETSTATES
  810.         if (res)
  811.             SetState(unconnected);
  812. #endif //NOSOCKETSTATES
  813.         return res;
  814.     }
  815.     else
  816. #endif //NOLAYERS
  817.     {
  818.         if (m_SocketData.nFamily == AF_UNSPEC)
  819.         {
  820. #ifndef NOSOCKETSTATES
  821.             SetState(unconnected);
  822. #endif //NOSOCKETSTATES
  823.             m_lEvent = lEvent;
  824.  
  825.             m_nSocketPort = nSocketPort;
  826.         
  827.             delete [] m_lpszSocketAddress;
  828.             if (lpszSocketAddress && *lpszSocketAddress)
  829.             {
  830.                 m_lpszSocketAddress = new TCHAR[_tcslen(lpszSocketAddress) + 1];
  831.                 _tcscpy(m_lpszSocketAddress, lpszSocketAddress);
  832.             }
  833.             else
  834.                 m_lpszSocketAddress = 0;
  835.  
  836.             return TRUE;
  837.         }
  838.         else
  839.         {
  840.             SOCKET hSocket = socket(m_SocketData.nFamily, nSocketType, 0);
  841.             if (hSocket == INVALID_SOCKET)
  842.                 return FALSE;
  843.             m_SocketData.hSocket = hSocket;
  844.             AttachHandle(hSocket);
  845.         
  846. #ifndef NOLAYERS
  847.             if (m_pFirstLayer)
  848.             {
  849.                 m_lEvent = lEvent;
  850.                 if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE) )
  851.                 {
  852.                     Close();
  853.                     return FALSE;
  854.                 }
  855.             }
  856.             else
  857. #endif //NOLAYERS
  858.             {
  859.                 if (!AsyncSelect(lEvent))
  860.                 {
  861.                     Close();
  862.                     return FALSE;
  863.                 }
  864.             }
  865.  
  866.             if (reusable && nSocketPort != 0)
  867.             {
  868.                 BOOL value = TRUE;
  869.                 SetSockOpt(SO_REUSEADDR, reinterpret_cast<const void*>(&value), sizeof(value));
  870.             }
  871.  
  872.             if (!Bind(nSocketPort, lpszSocketAddress))
  873.             {
  874.                 Close();
  875.                 return FALSE;
  876.             }
  877.  
  878. #ifndef NOSOCKETSTATES
  879.             SetState(unconnected);
  880. #endif //NOSOCKETSTATES
  881.         
  882.             return TRUE;
  883.         }
  884.     }
  885. }
  886.  
  887. void CAsyncSocketEx::OnReceive(int nErrorCode)
  888. {
  889. }
  890.  
  891. void CAsyncSocketEx::OnSend(int nErrorCode)
  892. {
  893. }
  894.  
  895. void CAsyncSocketEx::OnConnect(int nErrorCode)
  896. {
  897. }
  898.  
  899. void CAsyncSocketEx::OnAccept(int nErrorCode)
  900. {
  901. }
  902.  
  903. void CAsyncSocketEx::OnClose(int nErrorCode)
  904. {
  905. }
  906.  
  907. BOOL CAsyncSocketEx::Bind(UINT nSocketPort, LPCTSTR lpszSocketAddress)
  908. {
  909.     delete [] m_lpszSocketAddress;
  910.     if (lpszSocketAddress && *lpszSocketAddress)
  911.     {
  912.         m_lpszSocketAddress = new TCHAR[_tcslen(lpszSocketAddress) + 1];
  913.         _tcscpy(m_lpszSocketAddress, lpszSocketAddress);
  914.     }
  915.     else
  916.         m_lpszSocketAddress = 0;
  917.     m_nSocketPort = nSocketPort;
  918.  
  919.     if (m_SocketData.nFamily == AF_UNSPEC)
  920.         return TRUE;
  921.  
  922.     USES_CONVERSION;
  923.     
  924.     LPSTR lpszAscii = (lpszSocketAddress && *lpszSocketAddress) ? T2A((LPTSTR)lpszSocketAddress) : 0;
  925.     
  926.     if ((m_SocketData.nFamily == AF_INET6 || m_SocketData.nFamily == AF_INET) && lpszAscii)
  927.     {
  928.         if (!p_getaddrinfo)
  929.         {
  930.             if (m_SocketData.nFamily != AF_INET)
  931.             {
  932.                 WSASetLastError(WSAEPROTONOSUPPORT);
  933.                 return FALSE;
  934.             }
  935.             else
  936.             {
  937.                 unsigned long ip = inet_addr(lpszAscii);
  938.                 if (!ip)
  939.                 {
  940.                     WSASetLastError(WSAEINVAL);
  941.                     return FALSE;
  942.                 }
  943.  
  944.                 SOCKADDR_IN sockAddr;
  945.                 memset(&sockAddr, 0, sizeof(sockAddr));
  946.                 sockAddr.sin_family = m_SocketData.nFamily;
  947.                 sockAddr.sin_addr.s_addr = ip;
  948.                 sockAddr.sin_port = htons((u_short)nSocketPort);
  949.                 return Bind((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  950.             }
  951.         }
  952.         addrinfo hints, *res0, *res;
  953.         int error;
  954.         char port[10];
  955.         BOOL ret = FALSE;
  956.  
  957.         memset(&hints, 0, sizeof(addrinfo));
  958.         hints.ai_family = m_SocketData.nFamily;
  959.         hints.ai_socktype = SOCK_STREAM;
  960.         _snprintf(port, 9, "%lu", nSocketPort);
  961.         error = p_getaddrinfo(lpszAscii, port, &hints, &res0);
  962.         if (error)
  963.             return FALSE;
  964.  
  965.         for (res = res0; res; res = res->ai_next)
  966.             if (Bind(res->ai_addr, res->ai_addrlen))
  967.             {
  968.                 ret = TRUE;
  969.                 break;
  970.             }
  971.             else
  972.                 continue ;
  973.  
  974.             p_freeaddrinfo(res0);
  975.  
  976.             return ret ;
  977.     }
  978.     else if (!lpszAscii && m_SocketData.nFamily == AF_INET6)
  979.     {
  980.         SOCKADDR_IN6 sockAddr6;
  981.  
  982.         memset(&sockAddr6, 0, sizeof(sockAddr6));
  983.         sockAddr6.sin6_family = AF_INET6 ;
  984.         sockAddr6.sin6_addr = in6addr_any ;
  985.         sockAddr6.sin6_port = htons((u_short)nSocketPort);
  986.  
  987.         return Bind((SOCKADDR*)&sockAddr6, sizeof(sockAddr6));
  988.     }
  989.     else if (!lpszAscii && m_SocketData.nFamily == AF_INET)
  990.     {
  991.         SOCKADDR_IN sockAddr;
  992.  
  993.         memset(&sockAddr, 0, sizeof(sockAddr));
  994.         sockAddr.sin_family = AF_INET ;
  995.         sockAddr.sin_addr.s_addr = INADDR_ANY ;
  996.         sockAddr.sin_port = htons((u_short)nSocketPort);
  997.  
  998.         return Bind((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  999.     }
  1000.     else
  1001.         return FALSE ;
  1002. }
  1003.  
  1004. BOOL CAsyncSocketEx::Bind(const SOCKADDR* lpSockAddr, int nSockAddrLen)
  1005. {
  1006.     if (!bind(m_SocketData.hSocket, lpSockAddr, nSockAddrLen))
  1007.         return TRUE;
  1008.     else
  1009.         return FALSE;
  1010. }
  1011.  
  1012. void CAsyncSocketEx::AttachHandle(SOCKET hSocket)
  1013. {
  1014.     ASSERT(m_pLocalAsyncSocketExThreadData);
  1015.     VERIFY(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->AddSocket(this, m_SocketData.nSocketIndex));
  1016. #ifndef NOSOCKETSTATES
  1017.     SetState(attached);
  1018. #endif //NOSOCKETSTATES
  1019. }
  1020.  
  1021. void CAsyncSocketEx::DetachHandle(SOCKET hSocket)
  1022. {
  1023.     ASSERT(m_pLocalAsyncSocketExThreadData);
  1024.     if (!m_pLocalAsyncSocketExThreadData)
  1025.         return;
  1026.     ASSERT(m_pLocalAsyncSocketExThreadData->m_pHelperWindow);
  1027.     if (!m_pLocalAsyncSocketExThreadData->m_pHelperWindow)
  1028.         return;
  1029.     VERIFY(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->RemoveSocket(this, m_SocketData.nSocketIndex));
  1030. #ifndef NOSOCKETSTATES
  1031.     SetState(notsock);
  1032. #endif //NOSOCKETSTATES
  1033. }
  1034.  
  1035. void CAsyncSocketEx::Close()
  1036. {
  1037. #ifndef NOSOCKETSTATES
  1038.     m_nPendingEvents = 0;
  1039. #endif //NOSOCKETSTATES
  1040. #ifndef NOLAYERS
  1041.     if (m_pFirstLayer)
  1042.         m_pFirstLayer->Close();
  1043. #endif //NOLAYERS
  1044.     if (m_SocketData.hSocket != INVALID_SOCKET)
  1045.     {
  1046.         VERIFY((closesocket(m_SocketData.hSocket) != SOCKET_ERROR));
  1047.         DetachHandle(m_SocketData.hSocket);
  1048.         m_SocketData.hSocket = INVALID_SOCKET;
  1049.     }
  1050.     if (m_SocketData.addrInfo)
  1051.     {
  1052.         p_freeaddrinfo(m_SocketData.addrInfo);
  1053.         m_SocketData.addrInfo = 0;
  1054.         m_SocketData.nextAddr = 0;
  1055.     }
  1056.     m_SocketData.nFamily = AF_UNSPEC;
  1057.     delete [] m_lpszSocketAddress;
  1058.     m_lpszSocketAddress = 0;
  1059.     m_nSocketPort = 0;
  1060. #ifndef NOLAYERS
  1061.     RemoveAllLayers();
  1062. #endif //NOLAYERS
  1063.     delete [] m_pAsyncGetHostByNameBuffer;
  1064.     m_pAsyncGetHostByNameBuffer = NULL;
  1065.     if (m_hAsyncGetHostByNameHandle)
  1066.         WSACancelAsyncRequest(m_hAsyncGetHostByNameHandle);
  1067.     m_hAsyncGetHostByNameHandle = NULL;
  1068.     m_SocketData.onCloseCalled = false;
  1069. }
  1070.  
  1071. BOOL CAsyncSocketEx::InitAsyncSocketExInstance()
  1072. {
  1073.     //Check if already initialized
  1074.     if (m_pLocalAsyncSocketExThreadData)
  1075.         return TRUE;
  1076.  
  1077.     DWORD id=GetCurrentThreadId();
  1078.  
  1079.     m_sGlobalCriticalSection.Lock();
  1080.  
  1081.     //Get thread specific data
  1082.     if (m_spAsyncSocketExThreadDataList)
  1083.     {
  1084.         t_AsyncSocketExThreadDataList *pList=m_spAsyncSocketExThreadDataList;
  1085.         while (pList)
  1086.         {
  1087.             ASSERT(pList->pThreadData);
  1088.             ASSERT(pList->pThreadData->nInstanceCount>0);
  1089.  
  1090.             if (pList->pThreadData->nThreadId==id)
  1091.             {
  1092.                 m_pLocalAsyncSocketExThreadData=pList->pThreadData;
  1093.                 m_pLocalAsyncSocketExThreadData->nInstanceCount++;
  1094.                 break;
  1095.             }
  1096.             pList=pList->pNext;
  1097.         }
  1098.         //Current thread yet has no sockets
  1099.         if (!pList)
  1100.         {
  1101.             //Initialize data for current thread
  1102.             pList=new t_AsyncSocketExThreadDataList;
  1103.             pList->pNext=m_spAsyncSocketExThreadDataList;
  1104.             m_spAsyncSocketExThreadDataList=pList;
  1105.             m_pLocalAsyncSocketExThreadData=new t_AsyncSocketExThreadData;
  1106.             m_pLocalAsyncSocketExThreadData->nInstanceCount=1;
  1107.             m_pLocalAsyncSocketExThreadData->nThreadId=id;
  1108.             m_pLocalAsyncSocketExThreadData->m_pHelperWindow=new CAsyncSocketExHelperWindow(m_pLocalAsyncSocketExThreadData);
  1109.             m_spAsyncSocketExThreadDataList->pThreadData=m_pLocalAsyncSocketExThreadData;
  1110.         }
  1111.     }
  1112.     else
  1113.     {    //No thread has instances of CAsyncSocketEx; Initialize data
  1114.         m_spAsyncSocketExThreadDataList=new t_AsyncSocketExThreadDataList;
  1115.         m_spAsyncSocketExThreadDataList->pNext=0;
  1116.         m_pLocalAsyncSocketExThreadData=new t_AsyncSocketExThreadData;
  1117.         m_pLocalAsyncSocketExThreadData->nInstanceCount=1;
  1118.         m_pLocalAsyncSocketExThreadData->nThreadId=id;
  1119.         m_pLocalAsyncSocketExThreadData->m_pHelperWindow=new CAsyncSocketExHelperWindow(m_pLocalAsyncSocketExThreadData);
  1120.         m_spAsyncSocketExThreadDataList->pThreadData=m_pLocalAsyncSocketExThreadData;
  1121.  
  1122.         m_hDll = LoadLibrary(_T("WS2_32.dll"));
  1123.         if (m_hDll)
  1124.         {
  1125.             p_getaddrinfo = (t_getaddrinfo)GetProcAddress(m_hDll, "getaddrinfo");
  1126.             p_freeaddrinfo = (t_freeaddrinfo)GetProcAddress(m_hDll, "freeaddrinfo");
  1127.  
  1128.             if (!p_getaddrinfo || !p_freeaddrinfo)
  1129.             {
  1130.                 p_getaddrinfo = 0;
  1131.                 p_freeaddrinfo = 0;
  1132.                 FreeLibrary(m_hDll);
  1133.                 m_hDll = 0;
  1134.             }
  1135.         }
  1136.     }
  1137.     m_sGlobalCriticalSection.Unlock();
  1138.     return TRUE;
  1139. }
  1140.  
  1141. void CAsyncSocketEx::FreeAsyncSocketExInstance()
  1142. {
  1143.     //Check if already freed
  1144.     if (!m_pLocalAsyncSocketExThreadData)
  1145.         return;
  1146.  
  1147.     for (std::list<CAsyncSocketEx*>::iterator iter = m_pLocalAsyncSocketExThreadData->layerCloseNotify.begin(); iter != m_pLocalAsyncSocketExThreadData->layerCloseNotify.end(); iter++)
  1148.     {
  1149.         if (*iter != this)
  1150.             continue;
  1151.  
  1152.         m_pLocalAsyncSocketExThreadData->layerCloseNotify.erase(iter);
  1153.         if (m_pLocalAsyncSocketExThreadData->layerCloseNotify.empty())
  1154.             KillTimer(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->GetHwnd(), 1);
  1155.         break;
  1156.     }
  1157.  
  1158.     DWORD id=m_pLocalAsyncSocketExThreadData->nThreadId;
  1159.     m_sGlobalCriticalSection.Lock();
  1160.  
  1161.     ASSERT(m_spAsyncSocketExThreadDataList);
  1162.     t_AsyncSocketExThreadDataList *pList=m_spAsyncSocketExThreadDataList;
  1163.     t_AsyncSocketExThreadDataList *pPrev=0;
  1164.  
  1165.     //Serach for data for current thread and decrease instance count
  1166.     while (pList)
  1167.     {
  1168.         ASSERT(pList->pThreadData);
  1169.         ASSERT(pList->pThreadData->nInstanceCount>0);
  1170.  
  1171.         if (pList->pThreadData->nThreadId==id)
  1172.         {
  1173.             ASSERT(m_pLocalAsyncSocketExThreadData==pList->pThreadData);
  1174.             m_pLocalAsyncSocketExThreadData->nInstanceCount--;
  1175.  
  1176.             //Freeing last instance?
  1177.             //If so, destroy helper window
  1178.             if (!m_pLocalAsyncSocketExThreadData->nInstanceCount)
  1179.             {
  1180.                 delete m_pLocalAsyncSocketExThreadData->m_pHelperWindow;
  1181.                 delete m_pLocalAsyncSocketExThreadData;
  1182.                 if (pPrev)
  1183.                     pPrev->pNext=pList->pNext;
  1184.                 else
  1185.                     m_spAsyncSocketExThreadDataList=pList->pNext;
  1186.                 delete pList;
  1187.  
  1188.                 // Last thread closed, free dll
  1189.                 if (!m_spAsyncSocketExThreadDataList)
  1190.                 {
  1191.                     if (m_hDll)
  1192.                     {
  1193.                         p_getaddrinfo = 0;
  1194.                         p_freeaddrinfo = 0;
  1195.                         FreeLibrary(m_hDll);
  1196.                         m_hDll = 0;
  1197.                     }
  1198.                 }
  1199.                 break;
  1200.             }
  1201.  
  1202.             break;
  1203.         }
  1204.         pPrev=pList;
  1205.         pList=pList->pNext;
  1206.         ASSERT(pList);
  1207.     }
  1208.  
  1209.     m_sGlobalCriticalSection.Unlock();
  1210. }
  1211.  
  1212. int CAsyncSocketEx::Receive(void* lpBuf, int nBufLen, int nFlags /*=0*/)
  1213. {
  1214. #ifndef NOLAYERS
  1215.     if (m_pFirstLayer)
  1216.         return m_pFirstLayer->Receive(lpBuf, nBufLen, nFlags);
  1217.     else
  1218. #endif //NOLAYERS
  1219.         return recv(m_SocketData.hSocket, (LPSTR)lpBuf, nBufLen, nFlags);
  1220. }
  1221.  
  1222.  
  1223. int CAsyncSocketEx::Send(const void* lpBuf, int nBufLen, int nFlags /*=0*/)
  1224. {
  1225. #ifndef NOLAYERS
  1226.     if (m_pFirstLayer)
  1227.         return m_pFirstLayer->Send(lpBuf, nBufLen, nFlags);
  1228.     else
  1229. #endif //NOLAYERS
  1230.         return send(m_SocketData.hSocket, (LPSTR)lpBuf, nBufLen, nFlags);
  1231. }
  1232.  
  1233. BOOL CAsyncSocketEx::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
  1234. {
  1235. #ifndef NOLAYERS
  1236.     if (m_pFirstLayer)
  1237.     {
  1238.         BOOL res = m_pFirstLayer->Connect(lpszHostAddress, nHostPort);
  1239. #ifndef NOSOCKETSTATES
  1240.         if (res || GetLastError()==WSAEWOULDBLOCK)
  1241.             SetState(connecting);
  1242. #endif //NOSOCKETSTATES
  1243.         return res;
  1244.     } else
  1245. #endif //NOLAYERS
  1246.     if (m_SocketData.nFamily == AF_INET)
  1247.     {
  1248.         USES_CONVERSION;
  1249.  
  1250.         ASSERT(lpszHostAddress != NULL);
  1251.  
  1252.         SOCKADDR_IN sockAddr;
  1253.         memset(&sockAddr,0,sizeof(sockAddr));
  1254.  
  1255.         LPSTR lpszAscii = T2A((LPTSTR)lpszHostAddress);
  1256.         sockAddr.sin_family = AF_INET;
  1257.         sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
  1258.  
  1259.         if (sockAddr.sin_addr.s_addr == INADDR_NONE)
  1260.         {
  1261.             if (m_pAsyncGetHostByNameBuffer)
  1262.                 delete [] m_pAsyncGetHostByNameBuffer;
  1263.             m_pAsyncGetHostByNameBuffer=new char[MAXGETHOSTSTRUCT];
  1264.  
  1265.             m_nAsyncGetHostByNamePort=nHostPort;
  1266.  
  1267.             m_hAsyncGetHostByNameHandle=WSAAsyncGetHostByName(GetHelperWindowHandle(), WM_USER+1, lpszAscii, m_pAsyncGetHostByNameBuffer, MAXGETHOSTSTRUCT);
  1268.             if (!m_hAsyncGetHostByNameHandle)
  1269.                 return FALSE;
  1270.  
  1271.             WSASetLastError(WSAEWOULDBLOCK);
  1272. #ifndef NOSOCKETSTATES
  1273.             SetState(connecting);
  1274. #endif //NOSOCKETSTATES
  1275.             return FALSE;
  1276.         }
  1277.  
  1278.         sockAddr.sin_port = htons((u_short)nHostPort);
  1279.  
  1280.         return CAsyncSocketEx::Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  1281.     }
  1282.     else
  1283.     {
  1284.         if (!p_getaddrinfo)
  1285.         {
  1286.             WSASetLastError(WSAEPROTONOSUPPORT);
  1287.             return FALSE;
  1288.         }
  1289.  
  1290.         USES_CONVERSION;
  1291.  
  1292.         ASSERT( lpszHostAddress != NULL );
  1293.  
  1294.         if (m_SocketData.addrInfo)
  1295.         {
  1296.             p_freeaddrinfo(m_SocketData.addrInfo);
  1297.             m_SocketData.addrInfo = 0;
  1298.             m_SocketData.nextAddr = 0;
  1299.         }
  1300.  
  1301.         addrinfo hints;
  1302.         int error;
  1303.         BOOL ret = TRUE;
  1304.         char port[10];
  1305.  
  1306.         memset(&hints, 0, sizeof(addrinfo));
  1307.         hints.ai_family = m_SocketData.nFamily;
  1308.         hints.ai_socktype = SOCK_STREAM;
  1309.         _snprintf(port, 9, "%lu", nHostPort);
  1310.         error = p_getaddrinfo(T2CA(lpszHostAddress), port, &hints, &m_SocketData.addrInfo);
  1311.         if (error)
  1312.             return FALSE;
  1313.  
  1314.         for (m_SocketData.nextAddr = m_SocketData.addrInfo; m_SocketData.nextAddr; m_SocketData.nextAddr = m_SocketData.nextAddr->ai_next)
  1315.         {
  1316.             bool newSocket = false;
  1317.             if (m_SocketData.nFamily == AF_UNSPEC)
  1318.             {
  1319.                 newSocket = true;
  1320.                 m_SocketData.hSocket = socket(m_SocketData.nextAddr->ai_family, m_SocketData.nextAddr->ai_socktype, m_SocketData.nextAddr->ai_protocol);
  1321.  
  1322.                 if (m_SocketData.hSocket == INVALID_SOCKET)
  1323.                     continue;
  1324.  
  1325.                 m_SocketData.nFamily = m_SocketData.nextAddr->ai_family;
  1326.                 AttachHandle(m_SocketData.hSocket);
  1327.                 if (!AsyncSelect(m_lEvent))
  1328.                 {
  1329.                     if (newSocket)
  1330.                     {
  1331.                         DetachHandle(m_SocketData.hSocket);
  1332.                         closesocket(m_SocketData.hSocket);
  1333.                         m_SocketData.hSocket = INVALID_SOCKET;
  1334.                     }
  1335.                     continue;
  1336.                 }
  1337.             }
  1338.             else if (m_SocketData.hSocket == INVALID_SOCKET)
  1339.                 continue;
  1340.  
  1341. #ifndef NOLAYERS
  1342.             if (m_pFirstLayer)
  1343.             {
  1344.                 if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE))
  1345.                 {
  1346.                     if (newSocket)
  1347.                     {
  1348.                         m_SocketData.nFamily = AF_UNSPEC;
  1349.                         DetachHandle(m_SocketData.hSocket);
  1350.                         closesocket(m_SocketData.hSocket);
  1351.                         m_SocketData.hSocket = INVALID_SOCKET;
  1352.                     }
  1353.                     continue;
  1354.                 }
  1355.             }
  1356. #endif //NOLAYERS
  1357.  
  1358.             if (newSocket)
  1359.             {
  1360.                 m_SocketData.nFamily = m_SocketData.nextAddr->ai_family;
  1361.                 if (!Bind(m_nSocketPort, m_lpszSocketAddress))
  1362.                 { 
  1363.                     m_SocketData.nFamily = AF_UNSPEC;
  1364.                     DetachHandle(m_SocketData.hSocket);
  1365.                     closesocket(m_SocketData.hSocket);
  1366.                     m_SocketData.hSocket = INVALID_SOCKET;
  1367.                     continue; 
  1368.                 }
  1369.             }
  1370.  
  1371.             if (!(ret = CAsyncSocketEx::Connect(m_SocketData.nextAddr->ai_addr, m_SocketData.nextAddr->ai_addrlen)) && GetLastError() != WSAEWOULDBLOCK)
  1372.             {
  1373.                 if (newSocket)
  1374.                 {
  1375.                     m_SocketData.nFamily = AF_UNSPEC;
  1376.                     DetachHandle(m_SocketData.hSocket);
  1377.                     closesocket(m_SocketData.hSocket);
  1378.                     m_SocketData.hSocket = INVALID_SOCKET;
  1379.                 }
  1380.                 continue;
  1381.             }
  1382.  
  1383.             break;
  1384.         }
  1385.  
  1386.         if (m_SocketData.nextAddr)
  1387.             m_SocketData.nextAddr = m_SocketData.nextAddr->ai_next;
  1388.  
  1389.         if (!m_SocketData.nextAddr)
  1390.         {
  1391.             p_freeaddrinfo(m_SocketData.addrInfo);
  1392.             m_SocketData.nextAddr = 0;
  1393.             m_SocketData.addrInfo = 0;
  1394.         }
  1395.  
  1396.         if (m_SocketData.hSocket == INVALID_SOCKET || !ret)
  1397.             return FALSE;
  1398.         else
  1399.             return TRUE;
  1400.     }
  1401. }
  1402.  
  1403. BOOL CAsyncSocketEx::Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen)
  1404. {
  1405.     BOOL res;
  1406. #ifndef NOLAYERS
  1407.     if (m_pFirstLayer)
  1408.         res = SOCKET_ERROR!=m_pFirstLayer->Connect(lpSockAddr, nSockAddrLen);
  1409.     else
  1410. #endif //NOLAYERS
  1411.         res = SOCKET_ERROR!=connect(m_SocketData.hSocket, lpSockAddr, nSockAddrLen);
  1412.  
  1413. #ifndef NOSOCKETSTATES
  1414.     if (res || GetLastError()==WSAEWOULDBLOCK)
  1415.         SetState(connecting);
  1416. #endif //NOSOCKETSTATES
  1417.     return res;
  1418. }
  1419.  
  1420. BOOL CAsyncSocketEx::GetPeerName( CStdString& rPeerAddress, UINT& rPeerPort )
  1421. {
  1422. #ifndef NOLAYERS
  1423.     if (m_pFirstLayer)
  1424.         return m_pFirstLayer->GetPeerName(rPeerAddress, rPeerPort);
  1425. #endif NOLAYERS
  1426.  
  1427.     SOCKADDR* sockAddr = 0;
  1428.     int nSockAddrLen = 0;
  1429.  
  1430.     if (m_SocketData.nFamily == AF_INET6)
  1431.     {
  1432.         sockAddr = (SOCKADDR*)new SOCKADDR_IN6;
  1433.         nSockAddrLen = sizeof(SOCKADDR_IN6);
  1434.     } 
  1435.     else if (m_SocketData.nFamily == AF_INET)
  1436.     {
  1437.         sockAddr = (SOCKADDR*)new SOCKADDR_IN;
  1438.         nSockAddrLen = sizeof(SOCKADDR_IN);
  1439.     }
  1440.     else
  1441.     {
  1442.         WSASetLastError(WSAEOPNOTSUPP);
  1443.         return FALSE;
  1444.     }
  1445.  
  1446.     memset(sockAddr, 0, nSockAddrLen);
  1447.  
  1448.     BOOL bResult = GetPeerName(sockAddr, &nSockAddrLen);
  1449.  
  1450.     if (bResult)
  1451.     {
  1452.         if (m_SocketData.nFamily == AF_INET6)
  1453.         {
  1454.             rPeerPort = ntohs(((SOCKADDR_IN6*)sockAddr)->sin6_port);
  1455.             LPTSTR buf = Inet6AddrToString(((SOCKADDR_IN6*)sockAddr)->sin6_addr);
  1456.             rPeerAddress = buf;
  1457.             delete [] buf;
  1458.         }
  1459.         else if (m_SocketData.nFamily == AF_INET)
  1460.         {
  1461.             rPeerPort = ntohs(((SOCKADDR_IN*)sockAddr)->sin_port);
  1462.             rPeerAddress = inet_ntoa(((SOCKADDR_IN*)sockAddr)->sin_addr);
  1463.         }
  1464.         else
  1465.         {
  1466.             delete sockAddr;
  1467.             return FALSE;
  1468.         }
  1469.     }
  1470.     delete sockAddr;
  1471.  
  1472.     return bResult;
  1473. }
  1474.  
  1475. BOOL CAsyncSocketEx::GetPeerName( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
  1476. {
  1477. #ifndef NOLAYERS
  1478.     if (m_pFirstLayer)
  1479.         return m_pFirstLayer->GetPeerName(lpSockAddr, lpSockAddrLen);
  1480. #endif //NOLAYERS
  1481.  
  1482.     if (!getpeername(m_SocketData.hSocket, lpSockAddr, lpSockAddrLen))
  1483.         return TRUE;
  1484.     else
  1485.         return FALSE;
  1486. }
  1487.  
  1488. BOOL CAsyncSocketEx::GetSockName(CStdString& rSocketAddress, UINT& rSocketPort)
  1489. {
  1490.     SOCKADDR* sockAddr = 0;
  1491.     int nSockAddrLen = 0;
  1492.  
  1493.     if (m_SocketData.nFamily == AF_INET6)
  1494.     {
  1495.         sockAddr = (SOCKADDR*)new SOCKADDR_IN6;
  1496.         nSockAddrLen = sizeof(SOCKADDR_IN6);
  1497.     }
  1498.     else if (m_SocketData.nFamily == AF_INET)
  1499.     {
  1500.         sockAddr = (SOCKADDR*)new SOCKADDR_IN;
  1501.         nSockAddrLen = sizeof(SOCKADDR_IN);
  1502.     }
  1503.     else
  1504.     {
  1505.         WSASetLastError(WSAEOPNOTSUPP);
  1506.         return FALSE;
  1507.     }
  1508.  
  1509.     memset(sockAddr, 0, nSockAddrLen);
  1510.  
  1511.     BOOL bResult = GetSockName(sockAddr, &nSockAddrLen);
  1512.  
  1513.     if (bResult)
  1514.     {
  1515.         if (m_SocketData.nFamily == AF_INET6)
  1516.         {
  1517.             rSocketPort = ntohs(((SOCKADDR_IN6*)sockAddr)->sin6_port);
  1518.             LPTSTR buf = Inet6AddrToString(((SOCKADDR_IN6*)sockAddr)->sin6_addr);
  1519.             rSocketAddress = buf;
  1520.             delete [] buf;
  1521.         }
  1522.         else if (m_SocketData.nFamily == AF_INET)
  1523.         {
  1524.             rSocketPort = ntohs(((SOCKADDR_IN*)sockAddr)->sin_port);
  1525.             rSocketAddress = inet_ntoa(((SOCKADDR_IN*)sockAddr)->sin_addr);
  1526.         }
  1527.         else
  1528.         {
  1529.             delete sockAddr;
  1530.             return FALSE;
  1531.         }
  1532.     }
  1533.     delete sockAddr;
  1534.  
  1535.     return bResult;
  1536. }
  1537.  
  1538. BOOL CAsyncSocketEx::GetSockName( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
  1539. {
  1540.     if ( !getsockname(m_SocketData.hSocket, lpSockAddr, lpSockAddrLen) )
  1541.         return TRUE;
  1542.     else
  1543.         return FALSE;
  1544. }
  1545.  
  1546. BOOL CAsyncSocketEx::ShutDown(int nHow /*=sends*/)
  1547. {
  1548. #ifndef NOLAYERS
  1549.     if (m_pFirstLayer)
  1550.     {
  1551.         return m_pFirstLayer->ShutDown();
  1552.     }
  1553.     else
  1554. #endif //NOLAYERS
  1555.     {
  1556.         if (!shutdown(m_SocketData.hSocket, nHow))
  1557.             return TRUE;
  1558.         else
  1559.             return FALSE;
  1560.     }
  1561. }
  1562.  
  1563. SOCKET CAsyncSocketEx::Detach()
  1564. {
  1565.     SOCKET socket = m_SocketData.hSocket;
  1566.     DetachHandle(socket);
  1567.     m_SocketData.hSocket = INVALID_SOCKET;
  1568.     m_SocketData.nFamily = AF_UNSPEC;
  1569.     return socket;
  1570. }
  1571.  
  1572. BOOL CAsyncSocketEx::Attach(SOCKET hSocket, long lEvent /*= FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE*/)
  1573. {
  1574.     if (hSocket==INVALID_SOCKET || !hSocket)
  1575.         return FALSE;
  1576.  
  1577.     VERIFY(InitAsyncSocketExInstance());
  1578.     m_SocketData.hSocket = hSocket;
  1579.  
  1580.     sockaddr_storage addr;
  1581.     memset(&addr, 0, sizeof(sockaddr_storage));
  1582.     int len = sizeof(addr);
  1583.     if (getsockname(m_SocketData.hSocket, reinterpret_cast<sockaddr*>(&addr), &len) != 0)
  1584.         return FALSE;
  1585.     m_SocketData.nFamily = addr.ss_family;
  1586.  
  1587.     AttachHandle(hSocket);
  1588.  
  1589. #ifndef NOLAYERS
  1590.     if (m_pFirstLayer)
  1591.     {
  1592.         m_lEvent = lEvent;
  1593.         return !WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
  1594.     }
  1595.     else
  1596. #endif //NOLAYERS
  1597.     {
  1598.         return AsyncSelect(lEvent);
  1599.     }        
  1600. }
  1601.  
  1602. BOOL CAsyncSocketEx::AsyncSelect( long lEvent /*= FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE*/ )
  1603. {
  1604.     ASSERT(m_pLocalAsyncSocketExThreadData);
  1605.     m_lEvent = lEvent;
  1606. #ifndef NOLAYERS
  1607.     if (m_pFirstLayer)
  1608.         return TRUE;
  1609.     else
  1610. #endif //NOLAYERS
  1611.     {
  1612.         if (m_SocketData.hSocket == INVALID_SOCKET && m_SocketData.nFamily == AF_UNSPEC)
  1613.             return true;
  1614.  
  1615.         if ( !WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, lEvent) )
  1616.             return TRUE;
  1617.         else
  1618.             return FALSE;
  1619.     }
  1620.     return TRUE;
  1621. }
  1622.  
  1623. BOOL CAsyncSocketEx::Listen( int nConnectionBacklog /*=5*/ )
  1624. {
  1625. #ifndef NOLAYERS
  1626.     if (m_pFirstLayer)
  1627.         return m_pFirstLayer->Listen(nConnectionBacklog);
  1628. #endif //NOLAYERS
  1629.  
  1630.     if (!listen(m_SocketData.hSocket, nConnectionBacklog))
  1631.     {
  1632. #ifndef NOSOCKETSTATES
  1633.         SetState(listening);
  1634. #endif //NOSOCKETSTATES
  1635.         return TRUE;
  1636.     }
  1637.     else
  1638.         return FALSE;
  1639. }
  1640.  
  1641. BOOL CAsyncSocketEx::Accept( CAsyncSocketEx& rConnectedSocket, SOCKADDR* lpSockAddr /*=NULL*/, int* lpSockAddrLen /*=NULL*/ )
  1642. {
  1643.     ASSERT(rConnectedSocket.m_SocketData.hSocket == INVALID_SOCKET);
  1644. #ifndef NOLAYERS
  1645.     if (m_pFirstLayer)
  1646.     {
  1647.         return m_pFirstLayer->Accept(rConnectedSocket, lpSockAddr, lpSockAddrLen);
  1648.     }
  1649.     else
  1650. #endif //NOLAYERS
  1651.     {
  1652.         SOCKET hTemp = accept(m_SocketData.hSocket, lpSockAddr, lpSockAddrLen);
  1653.  
  1654.         if (hTemp == INVALID_SOCKET)
  1655.             return FALSE;
  1656.         VERIFY(rConnectedSocket.InitAsyncSocketExInstance());
  1657.         rConnectedSocket.m_SocketData.hSocket=hTemp;
  1658.         rConnectedSocket.AttachHandle(hTemp);
  1659.         rConnectedSocket.SetFamily(GetFamily());
  1660. #ifndef NOSOCKETSTATES
  1661.         rConnectedSocket.SetState(connected);
  1662. #endif //NOSOCKETSTATES
  1663.     }
  1664.     return TRUE;
  1665. }
  1666.  
  1667. BOOL CAsyncSocketEx::IOCtl( long lCommand, DWORD* lpArgument )
  1668. {
  1669.     return ioctlsocket(m_SocketData.hSocket, lCommand, lpArgument) != SOCKET_ERROR;
  1670. }
  1671.  
  1672. int CAsyncSocketEx::GetLastError()
  1673. {
  1674.     return WSAGetLastError();
  1675. }
  1676.  
  1677. BOOL CAsyncSocketEx::TriggerEvent(long lEvent)
  1678. {
  1679.     if (m_SocketData.hSocket==INVALID_SOCKET)
  1680.         return FALSE;
  1681.  
  1682.     ASSERT(m_pLocalAsyncSocketExThreadData);
  1683.     ASSERT(m_pLocalAsyncSocketExThreadData->m_pHelperWindow);
  1684.     ASSERT(m_SocketData.nSocketIndex!=-1);
  1685.  
  1686. #ifndef NOLAYERS
  1687.     if (m_pFirstLayer)
  1688.     {
  1689.         CAsyncSocketExLayer::t_LayerNotifyMsg *pMsg = new CAsyncSocketExLayer::t_LayerNotifyMsg;
  1690.         pMsg->hSocket = m_SocketData.hSocket;
  1691.         pMsg->lEvent=lEvent%0xFFFF;
  1692.         pMsg->pLayer=0;
  1693.         BOOL res=PostMessage(GetHelperWindowHandle(), WM_USER, (WPARAM)m_SocketData.nSocketIndex, (LPARAM)pMsg);
  1694.         if (!res)
  1695.             delete pMsg;
  1696.         return res;
  1697.     }
  1698.     else
  1699. #endif //NOLAYERS
  1700.         return PostMessage(GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, m_SocketData.hSocket, lEvent%0xFFFF);
  1701.  
  1702. }
  1703.  
  1704. SOCKET CAsyncSocketEx::GetSocketHandle()
  1705. {
  1706.     return m_SocketData.hSocket;
  1707. }
  1708.  
  1709. HWND CAsyncSocketEx::GetHelperWindowHandle()
  1710. {
  1711.     if (!m_pLocalAsyncSocketExThreadData)
  1712.         return 0;
  1713.     if (!m_pLocalAsyncSocketExThreadData->m_pHelperWindow)
  1714.         return 0;
  1715.     return m_pLocalAsyncSocketExThreadData->m_pHelperWindow->GetHwnd();
  1716. }
  1717.  
  1718. #ifndef NOLAYERS
  1719. BOOL CAsyncSocketEx::AddLayer(CAsyncSocketExLayer *pLayer)
  1720. {
  1721.     ASSERT(pLayer);
  1722.  
  1723.     pLayer->m_nFamily = m_SocketData.nFamily;
  1724.  
  1725.     if (m_pFirstLayer)
  1726.     {
  1727.         ASSERT(m_pLastLayer);
  1728.         m_pLastLayer=m_pLastLayer->AddLayer(pLayer, this);
  1729.         return m_pLastLayer?TRUE:FALSE;
  1730.     }
  1731.     else
  1732.     {
  1733.         ASSERT(!m_pLastLayer);
  1734.         pLayer->Init(0, this);
  1735.         m_pFirstLayer=pLayer;
  1736.         m_pLastLayer=m_pFirstLayer;
  1737.         if (m_SocketData.hSocket != INVALID_SOCKET)
  1738.             if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE))
  1739.                 return FALSE;
  1740.     }
  1741.  
  1742.     return TRUE;
  1743. }
  1744.  
  1745. void CAsyncSocketEx::RemoveAllLayers()
  1746. {
  1747.     for (std::list<t_callbackMsg>::iterator iter = m_pendingCallbacks.begin(); iter != m_pendingCallbacks.end(); iter++)
  1748.         delete [] iter->str;
  1749.     m_pendingCallbacks.clear();
  1750.  
  1751.     m_pFirstLayer = 0;
  1752.     m_pLastLayer = 0;
  1753.  
  1754.     if (!m_pLocalAsyncSocketExThreadData)
  1755.         return;
  1756.     if (!m_pLocalAsyncSocketExThreadData->m_pHelperWindow)
  1757.         return;
  1758.     m_pLocalAsyncSocketExThreadData->m_pHelperWindow->RemoveLayers(this);
  1759. }
  1760.  
  1761. int CAsyncSocketEx::OnLayerCallback(std::list<t_callbackMsg>& callbacks)
  1762. {
  1763.     for (std::list<t_callbackMsg>::iterator iter = callbacks.begin(); iter != callbacks.end(); iter++)
  1764.     {
  1765.         delete [] iter->str;
  1766.     }
  1767.     return 0;
  1768. }
  1769.  
  1770. BOOL CAsyncSocketEx::IsLayerAttached() const
  1771. {
  1772.     return m_pFirstLayer ? TRUE : FALSE;
  1773. }
  1774. #endif //NOLAYERS
  1775.  
  1776. BOOL CAsyncSocketEx::GetSockOpt(int nOptionName, void* lpOptionValue, int* lpOptionLen, int nLevel /*=SOL_SOCKET*/)
  1777. {
  1778.     return (SOCKET_ERROR != getsockopt(m_SocketData.hSocket, nLevel, nOptionName, (LPSTR)lpOptionValue, lpOptionLen));
  1779. }
  1780.  
  1781. BOOL CAsyncSocketEx::SetSockOpt(int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel /*=SOL_SOCKET*/)
  1782. {
  1783.     return (SOCKET_ERROR != setsockopt(m_SocketData.hSocket, nLevel, nOptionName, (LPSTR)lpOptionValue, nOptionLen));
  1784. }
  1785.  
  1786. #ifndef NOSOCKETSTATES
  1787.  
  1788. int CAsyncSocketEx::GetState() const
  1789. {
  1790.     return m_nState;
  1791. }
  1792.  
  1793. void CAsyncSocketEx::SetState(int nState)
  1794. {
  1795.     m_nState = nState;
  1796. }
  1797.  
  1798. #endif //NOSOCKETSTATES
  1799.  
  1800. int CAsyncSocketEx::GetFamily() const
  1801. {
  1802.     return m_SocketData.nFamily;
  1803. }
  1804.  
  1805. bool CAsyncSocketEx::SetFamily(int nFamily)
  1806. {
  1807.     if (m_SocketData.nFamily != AF_UNSPEC)
  1808.         return false;
  1809.  
  1810.     m_SocketData.nFamily = nFamily;
  1811.     return true;    
  1812. }
  1813.  
  1814. bool CAsyncSocketEx::TryNextProtocol()
  1815. {
  1816.     DetachHandle(m_SocketData.hSocket);
  1817.     closesocket(m_SocketData.hSocket);
  1818.     m_SocketData.hSocket = INVALID_SOCKET;
  1819.  
  1820.     BOOL ret = FALSE;
  1821.     for (; m_SocketData.nextAddr; m_SocketData.nextAddr = m_SocketData.nextAddr->ai_next)
  1822.     {
  1823.         m_SocketData.hSocket = socket(m_SocketData.nextAddr->ai_family, m_SocketData.nextAddr->ai_socktype, m_SocketData.nextAddr->ai_protocol);
  1824.  
  1825.         if (m_SocketData.hSocket == INVALID_SOCKET)
  1826.             continue;
  1827.  
  1828.         AttachHandle(m_SocketData.hSocket);
  1829.         m_SocketData.nFamily = m_SocketData.nextAddr->ai_family;
  1830.         if (!AsyncSelect(m_lEvent))
  1831.         {
  1832.             DetachHandle(m_SocketData.hSocket);
  1833.             closesocket(m_SocketData.hSocket);
  1834.             m_SocketData.hSocket = INVALID_SOCKET;
  1835.             continue;
  1836.         }
  1837.  
  1838. #ifndef NOLAYERS
  1839.         if (m_pFirstLayer)
  1840.         {
  1841.             if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE))
  1842.             {
  1843.                 DetachHandle(m_SocketData.hSocket);
  1844.                 closesocket(m_SocketData.hSocket);
  1845.                 m_SocketData.hSocket = INVALID_SOCKET;
  1846.                 continue;
  1847.             }
  1848.         }
  1849. #endif //NOLAYERS
  1850.  
  1851.         if (!Bind(m_nSocketPort, m_lpszSocketAddress))
  1852.         { 
  1853.             DetachHandle(m_SocketData.hSocket);
  1854.             closesocket(m_SocketData.hSocket);
  1855.             m_SocketData.hSocket = INVALID_SOCKET;
  1856.             continue; 
  1857.         }
  1858.  
  1859.         ret = CAsyncSocketEx::Connect(m_SocketData.nextAddr->ai_addr, m_SocketData.nextAddr->ai_addrlen);
  1860.         if (!ret && GetLastError() != WSAEWOULDBLOCK)
  1861.         {
  1862.             DetachHandle(m_SocketData.hSocket);
  1863.             closesocket(m_SocketData.hSocket);
  1864.             m_SocketData.hSocket = INVALID_SOCKET;
  1865.             continue;
  1866.         }
  1867.  
  1868.         ret = true;
  1869.         break;
  1870.     }
  1871.  
  1872.     if (m_SocketData.nextAddr)
  1873.         m_SocketData.nextAddr = m_SocketData.nextAddr->ai_next;
  1874.  
  1875.     if (!m_SocketData.nextAddr)
  1876.     {
  1877.         p_freeaddrinfo(m_SocketData.addrInfo);
  1878.         m_SocketData.nextAddr = 0;
  1879.         m_SocketData.addrInfo = 0;
  1880.     }
  1881.  
  1882.     if (m_SocketData.hSocket == INVALID_SOCKET || !ret)
  1883.         return FALSE;
  1884.     else
  1885.         return TRUE;
  1886. }
  1887.  
  1888. #ifndef NOLAYERS
  1889.  
  1890. void CAsyncSocketEx::AddCallbackNotification(const t_callbackMsg& msg)
  1891. {
  1892.     m_pendingCallbacks.push_back(msg);
  1893.  
  1894.     if(m_pendingCallbacks.size() == 1 && m_SocketData.nSocketIndex != -1)
  1895.         PostMessage(GetHelperWindowHandle(), WM_USER + 2, (WPARAM)m_SocketData.nSocketIndex, 0);
  1896. }
  1897.  
  1898. #endif //NOLAYERS
  1899.  
  1900. void CAsyncSocketEx::ResendCloseNotify()
  1901. {
  1902.     for (std::list<CAsyncSocketEx*>::iterator iter = m_pLocalAsyncSocketExThreadData->layerCloseNotify.begin(); iter != m_pLocalAsyncSocketExThreadData->layerCloseNotify.end(); iter++)
  1903.     {
  1904.         if (*iter == this)
  1905.             return;
  1906.     }
  1907.     m_pLocalAsyncSocketExThreadData->layerCloseNotify.push_back(this);
  1908.     if (m_pLocalAsyncSocketExThreadData->layerCloseNotify.size() == 1)
  1909.     {
  1910.         SetTimer(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->GetHwnd(), 1, 10, 0);
  1911.     }
  1912. }
  1913.